#include "OneWire.h"
#include "intrins.h"

sbit OneWire_DQ = P1^4;

void Delay480us()		//@11.0592MHz
{
	unsigned char i, j;
	i = 6;	j = 38;
	do
	{
		while (--j);
	} while (--i);
}

/*初始化
	主机 将总线拉低至少480us，然后释放总线，
	等待15~60us后，存在的 从机 会拉低总线60~240us以响应 主机
	之后 从机 将释放总线
*/
//单总线初始化时序
void OneWire_Init(void)
{
	unsigned char ackbit;
	unsigned char i;
	
	OneWire_DQ = 1;
	OneWire_DQ = 0; Delay480us();	//总线拉低480us
	OneWire_DQ = 1;					//释放总线
	i = 138; while (--i);			//延时等待50us
	ackbit = OneWire_DQ; Delay480us();	//读取一下是否为0，并且延时等待480us	
}

/*发送一位
	主机将总线拉低60~120us，然后释放总线，表示发送0；
	主机将总线拉低1~15us，然后释放总线，表示发送1。
	从机 将在总线拉低30us后读取电平，整个时间片应大于60us
*/
//发送一位数据，0或1
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ = 1;
	OneWire_DQ = 0; 	i = 28;	 while (--i);	//总线拉低10us
	OneWire_DQ = Bit;	i = 138; while (--i);	//将Bit送回总线上再延时50us,检测Bit看变化赋值，比较巧妙的思想
	OneWire_DQ = 1;	//最终释放总线
}

/*接收一位
	主机将总线拉低1~15us，然后释放总线，并在拉低后15us内读取总线电平（尽量贴近15us末尾）
	读取为低电平则为接收0，读取为高电平则为接收1，整个时间片应大于60us
	*/
//接收一位数据 0或1
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i;
	unsigned char Bit;
	
	OneWire_DQ = 0;		i = 14;	 while (--i);	//先把总线拉低5us
	OneWire_DQ = 1;		i = 14;	 while (--i);	//释放总线5us
	Bit = OneWire_DQ;	//此时读取电平，数据0会把电平拉低，数据1仍然置高
	i = 138; while (--i);	//延时50us，满足时序要求	
	return Bit;
}

//发送一字节数据，从低位到高位依次发送
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for (i = 0; i < 8; i ++)
		OneWire_SendBit(Byte & (0x01<<i));
}

//接收一字节数据，从低位到高位依次接收
unsigned char OneWire_ReceiveByte(void)
{
	unsigned Byte = 0x00;
	unsigned char i;
	for (i = 0; i < 8; i ++)
	{
		//这个if判断，判断为0的时候，Byte当前位还是0，但是变量i正常++
		if( OneWire_ReceiveBit() )		//只有接收1才会执行下面的语句
			Byte |= 0x01<<i;		//从低位到高位依次取出	
	}
	return Byte;
}
